package com.ruoyi.websocket;

import com.ruoyi.socket.config.BinanceProxyConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.net.Authenticator;
import java.net.InetSocketAddress;
import java.net.PasswordAuthentication;
import java.net.Proxy;

/**
 * 币安WebSocket代理配置类
 * 基于币安官方Java连接器的代理认证实现
 * 参考：https://github.com/binance/binance-connector-java
 */
@Component
@Slf4j
public class BinanceWebSocketProxyConfig {
    
    @Resource
    private BinanceProxyConfig binanceProxyConfig;
    
    /**
     * 币安推荐的代理认证器实现
     */
    private static class BinanceProxyAuthenticator extends Authenticator {
        private final String username;
        private final String password;
        
        public BinanceProxyAuthenticator(String username, String password) {
            this.username = username;
            this.password = password;
        }
        
        @Override
        protected PasswordAuthentication getPasswordAuthentication() {
            // 币安官方推荐：只为代理认证提供凭据
            if (getRequestorType() == RequestorType.PROXY) {
                log.debug("币安代理认证 - 主机: {}, 端口: {}, 用户: {}", 
                        getRequestingHost(), getRequestingPort(), username);
                return new PasswordAuthentication(username, password.toCharArray());
            }
            return null;
        }
    }
    
    /**
     * 配置币安WebSocket代理
     * 基于币安官方推荐的方法
     */
    public void configureBinanceWebSocketProxy() {
        if (!binanceProxyConfig.isEnabled() || !binanceProxyConfig.isValidConfig()) {
            log.info("币安代理配置无效或未启用");
            return;
        }
        
        try {
            // 关键：解决Java 8u111+的Basic认证问题
            // 这是币安官方文档中提到的重要配置
            System.setProperty("jdk.http.auth.tunneling.disabledSchemes", "");
            
            // 币安推荐的系统属性配置
            System.setProperty("http.proxyHost", binanceProxyConfig.getHost());
            System.setProperty("http.proxyPort", String.valueOf(binanceProxyConfig.getPort()));
            System.setProperty("https.proxyHost", binanceProxyConfig.getHost());
            System.setProperty("https.proxyPort", String.valueOf(binanceProxyConfig.getPort()));
            
            // 设置代理认证
            if (binanceProxyConfig.getUsernameTemplate() != null && binanceProxyConfig.getPassword() != null) {
                String currentUsername = binanceProxyConfig.getCurrentUsername();
                String password = binanceProxyConfig.getPassword();
                
                // 系统属性方式（某些库需要）
                System.setProperty("http.proxyUser", currentUsername);
                System.setProperty("http.proxyPassword", password);
                System.setProperty("https.proxyUser", currentUsername);
                System.setProperty("https.proxyPassword", password);
                
                // 币安推荐的Authenticator方式
                Authenticator.setDefault(new BinanceProxyAuthenticator(currentUsername, password));
                
                log.info("币安WebSocket代理认证已配置 - 用户: {}, 代理: {}:{}", 
                        currentUsername, binanceProxyConfig.getHost(), binanceProxyConfig.getPort());
            }
            
        } catch (Exception e) {
            log.error("配置币安WebSocket代理失败", e);
        }
    }
    
    /**
     * 创建代理对象（用于OkHttp等客户端）
     */
    public Proxy createProxy() {
        if (!binanceProxyConfig.isEnabled() || !binanceProxyConfig.isValidConfig()) {
            return Proxy.NO_PROXY;
        }
        
        return new Proxy(Proxy.Type.HTTP, 
                new InetSocketAddress(binanceProxyConfig.getHost(), binanceProxyConfig.getPort()));
    }
    
    /**
     * 获取代理认证器（用于OkHttp等客户端）
     */
    public Authenticator createProxyAuthenticator() {
        if (!binanceProxyConfig.isEnabled() || !binanceProxyConfig.isValidConfig()) {
            return null;
        }
        
        if (binanceProxyConfig.getUsernameTemplate() == null || binanceProxyConfig.getPassword() == null) {
            return null;
        }
        
        return new BinanceProxyAuthenticator(
                binanceProxyConfig.getCurrentUsername(), 
                binanceProxyConfig.getPassword());
    }
    
    /**
     * 刷新代理认证（当随机数过期时）
     */
    public void refreshProxyAuth() {
        if (!binanceProxyConfig.isEnabled() || !binanceProxyConfig.isValidConfig()) {
            return;
        }
        
        if (binanceProxyConfig.isRandomExpired()) {
            log.info("币安代理随机数已过期，正在刷新...");
            binanceProxyConfig.generateNewRandom();
            
            // 重新配置代理认证
            configureBinanceWebSocketProxy();
        }
    }
    
    /**
     * 获取当前代理信息
     */
    public String getProxyInfo() {
        if (!binanceProxyConfig.isEnabled()) {
            return "币安代理未启用";
        }
        
        return String.format("币安代理: %s:%s, 用户: %s, 状态: %s",
                binanceProxyConfig.getHost(),
                binanceProxyConfig.getPort(),
                binanceProxyConfig.getCurrentUsername(),
                binanceProxyConfig.isValidConfig() ? "有效" : "无效");
    }
} 